/**
 * 权限管理通用逻辑 Hook
 *
 * 抽取权限检查的通用业务逻辑
 * 包括权限验证、角色检查、路由权限等功能
 */

import { ref, computed, onMounted, type Ref } from "vue";
import { useUserStore } from "@/store/modules/user";
import { useRoute } from "vue-router";
import { WMS_PERMISSIONS, USER_ROLES } from "@/utils/sys/permission";

/**
 * 权限Hook配置
 */
interface UsePermissionOptions {
  /** 是否立即检查权限 */
  immediate?: boolean;
  /** 权限缓存时间(毫秒) */
  cacheTime?: number;
}

/**
 * 权限Hook返回值
 */
interface UsePermissionReturn {
  // 状态
  userPermissions: Ref<string[]>;
  userRoles: Ref<string[]>;
  isAdmin: Ref<boolean>;
  loading: Ref<boolean>;

  // 方法
  hasPermission: (permission: string | string[]) => boolean;
  hasRole: (role: string | string[]) => boolean;
  hasAnyPermission: (permissions: string[]) => boolean;
  hasAllPermissions: (permissions: string[]) => boolean;
  hasAnyRole: (roles: string[]) => boolean;
  hasAllRoles: (roles: string[]) => boolean;
  checkRoutePermission: (route?: string) => boolean;
  checkWmsPermission: (module: string, action: string) => boolean;
  refreshPermissions: () => Promise<void>;
  canAccess: (resource: string, action?: string) => boolean;
}

/**
 * 权限管理通用Hook
 */
export function usePermission(
  options: UsePermissionOptions = {},
): UsePermissionReturn {
  const { immediate = true, cacheTime = 5 * 60 * 1000 } = options; // 默认5分钟缓存

  const userStore = useUserStore();
  const route = useRoute();

  // 状态
  const userPermissions = ref<string[]>([]);
  const userRoles = ref<string[]>([]);
  const loading = ref(false);
  const lastCacheTime = ref(0);

  // 计算属性
  const isAdmin = computed(() => userRoles.value.includes("admin"));

  /**
   * 检查单个或多个权限
   */
  const hasPermission = (permission: string | string[]): boolean => {
    if (!permission) return true;

    const permissions = Array.isArray(permission) ? permission : [permission];
    return permissions.some((p) => userPermissions.value.includes(p));
  };

  /**
   * 检查单个或多个角色
   */
  const hasRole = (role: string | string[]): boolean => {
    if (!role) return true;

    const roles = Array.isArray(role) ? role : [role];
    return roles.some((r) => userRoles.value.includes(r));
  };

  /**
   * 检查是否拥有任意一个权限
   */
  const hasAnyPermission = (permissions: string[]): boolean => {
    return permissions.some((p) => userPermissions.value.includes(p));
  };

  /**
   * 检查是否拥有所有权限
   */
  const hasAllPermissions = (permissions: string[]): boolean => {
    return permissions.every((p) => userPermissions.value.includes(p));
  };

  /**
   * 检查是否拥有任意一个角色
   */
  const hasAnyRole = (roles: string[]): boolean => {
    return roles.some((r) => userRoles.value.includes(r));
  };

  /**
   * 检查是否拥有所有角色
   */
  const hasAllRoles = (roles: string[]): boolean => {
    return roles.every((r) => userRoles.value.includes(r));
  };

  /**
   * 检查路由权限
   */
  const checkRoutePermission = (routePath?: string): boolean => {
    const targetRoute = routePath || route.path;

    // 管理员拥有所有权限
    if (isAdmin.value) return true;

    // 检查路由meta中的权限配置
    const routePermission = route.meta?.permission;
    if (routePermission) {
      return hasPermission(routePermission);
    }

    // 检查路由meta中的角色配置
    const routeRoles = route.meta?.roles;
    if (routeRoles) {
      return hasRole(routeRoles);
    }

    return true;
  };

  /**
   * 检查WMS模块权限
   */
  const checkWmsPermission = (module: string, action: string): boolean => {
    const permissionKey = `${module}:${action}`;

    // 检查WMS权限常量中是否存在
    const wmsPermission = (WMS_PERMISSIONS as any)[module]?.[action];
    if (wmsPermission) {
      return hasPermission(wmsPermission);
    }

    // 检查通用权限格式
    return hasPermission(permissionKey);
  };

  /**
   * 刷新权限信息
   */
  const refreshPermissions = async (): Promise<void> => {
    try {
      loading.value = true;

      // 从用户store获取最新权限信息
      await userStore.getInfo();

      userPermissions.value = userStore.permissions || [];
      userRoles.value = userStore.roles || [];
      lastCacheTime.value = Date.now();
    } catch (error) {
      console.error("刷新权限信息失败:", error);
    } finally {
      loading.value = false;
    }
  };

  /**
   * 通用资源访问权限检查
   */
  const canAccess = (resource: string, action: string = "view"): boolean => {
    // 管理员拥有所有权限
    if (isAdmin.value) return true;

    // 检查具体权限
    const permission = `${resource}:${action}`;
    if (hasPermission(permission)) return true;

    // 检查通配符权限
    const wildcardPermission = `${resource}:*`;
    if (hasPermission(wildcardPermission)) return true;

    // 检查模块级权限
    const modulePermission = resource.split(":")[0] + ":*";
    if (hasPermission(modulePermission)) return true;

    return false;
  };

  /**
   * 初始化权限信息
   */
  const initPermissions = async (): Promise<void> => {
    const now = Date.now();

    // 检查缓存是否有效
    if (lastCacheTime.value && now - lastCacheTime.value < cacheTime) {
      return;
    }

    await refreshPermissions();
  };

  // 生命周期
  if (immediate) {
    onMounted(() => {
      initPermissions();
    });
  } else {
    // 从store同步当前权限信息
    userPermissions.value = userStore.permissions || [];
    userRoles.value = userStore.roles || [];
  }

  return {
    // 状态
    userPermissions,
    userRoles,
    isAdmin,
    loading,

    // 方法
    hasPermission,
    hasRole,
    hasAnyPermission,
    hasAllPermissions,
    hasAnyRole,
    hasAllRoles,
    checkRoutePermission,
    checkWmsPermission,
    refreshPermissions,
    canAccess,
  };
}

/**
 * 权限装饰器Hook
 * 用于快速创建带权限检查的组件方法
 */
export function usePermissionGuard() {
  const { hasPermission, hasRole, canAccess } = usePermission();

  /**
   * 权限保护装饰器
   */
  const withPermission = (permission: string | string[]) => {
    return (
      target: any,
      propertyKey: string,
      descriptor: PropertyDescriptor,
    ) => {
      const originalMethod = descriptor.value;

      descriptor.value = function (...args: any[]) {
        if (!hasPermission(permission)) {
          ElMessage.warning("您没有执行此操作的权限");
          return;
        }
        return originalMethod.apply(this, args);
      };
    };
  };

  /**
   * 角色保护装饰器
   */
  const withRole = (role: string | string[]) => {
    return (
      target: any,
      propertyKey: string,
      descriptor: PropertyDescriptor,
    ) => {
      const originalMethod = descriptor.value;

      descriptor.value = function (...args: any[]) {
        if (!hasRole(role)) {
          ElMessage.warning("您的角色无权执行此操作");
          return;
        }
        return originalMethod.apply(this, args);
      };
    };
  };

  /**
   * 资源访问保护装饰器
   */
  const withAccess = (resource: string, action: string = "view") => {
    return (
      target: any,
      propertyKey: string,
      descriptor: PropertyDescriptor,
    ) => {
      const originalMethod = descriptor.value;

      descriptor.value = function (...args: any[]) {
        if (!canAccess(resource, action)) {
          ElMessage.warning("您无权访问此资源");
          return;
        }
        return originalMethod.apply(this, args);
      };
    };
  };

  return {
    withPermission,
    withRole,
    withAccess,
  };
}

/**
 * WMS权限常量
 */
export const WMS_PERMISSION_KEYS = {
  // 商品管理
  ITEM: {
    VIEW: "wms:item:view",
    ADD: "wms:item:add",
    EDIT: "wms:item:edit",
    DELETE: "wms:item:delete",
    EXPORT: "wms:item:export",
    IMPORT: "wms:item:import",
  },

  // 仓库管理
  WAREHOUSE: {
    VIEW: "wms:warehouse:view",
    ADD: "wms:warehouse:add",
    EDIT: "wms:warehouse:edit",
    DELETE: "wms:warehouse:delete",
  },

  // 库区管理
  AREA: {
    VIEW: "wms:area:view",
    ADD: "wms:area:add",
    EDIT: "wms:area:edit",
    DELETE: "wms:area:delete",
  },

  // 库存管理
  INVENTORY: {
    VIEW: "wms:inventory:view",
    ADJUST: "wms:inventory:adjust",
    TRANSFER: "wms:inventory:transfer",
    COUNT: "wms:inventory:count",
  },

  // 订单管理
  ORDER: {
    VIEW: "wms:order:view",
    CREATE: "wms:order:create",
    EDIT: "wms:order:edit",
    DELETE: "wms:order:delete",
    APPROVE: "wms:order:approve",
    REJECT: "wms:order:reject",
  },

  // 报表管理
  REPORT: {
    VIEW: "wms:report:view",
    EXPORT: "wms:report:export",
    GENERATE: "wms:report:generate",
  },
} as const;
